package core;

import static view.Constants.BUFFER_SIZE;

/**
 * @author Mostafa Mahmod Mahmod Eweda
 * <pre>mostafa_eweda17@yahoo.com</pre>
 * @since JDK 1.6
 * @version 1.0
 * 
 * The bit manipulator buffer for the addition of the characters into a byte array buffer
 * before writing to the file for giving best performance
 * 
 * for some of the implementing classes:
 * @see CompressedChar
 */
public class CompressedBuffer {

	private byte[] buff;
	private int rowIndex;
	private int columnIndex;
	private final byte full;

	public CompressedBuffer()
	{
		this.full = -1;
		buff = new byte[BUFFER_SIZE];
		rowIndex = 0;
		columnIndex = -1;
	}

	/**
	 * @param ch the character wanted to be saved to the buffer
	 * @param length the length of the sequence taken from the character
	 * @return the number of bits couldn't be stored in that buffer
	 */
	public int add(CompressedChar ch, int length)
	{
		byte mask = 0;
		for (int i = length - 1; i >= 0; i--) {
			if (columnIndex == 7)
			{
//				System.out.print(' ');
				columnIndex = 0;
				if (rowIndex == buff.length - 1)
					return i + 1;
				else
					rowIndex++;
			}
			else
				columnIndex ++;
			mask =  (byte) (1 << i);
			byte result = (byte) (mask & ch.sequence);
			if (result == 0)
			{
				buff[rowIndex] &= full - 1 << (7 - columnIndex);
//				System.out.print('0');
			}
			else
			{
				buff[rowIndex] |= 1 << (7 - columnIndex);
//				System.out.print('1');
			}
		}
		return 0;
	}

	public byte[] bytes()
	{
		return buff;
	}

	public void reset()
	{
		columnIndex = -1;
		rowIndex = 0;
	}

	public int rows()
	{
		return rowIndex + 1;
	}

	public int columns()
	{
		return columnIndex + 1;
	}

	public byte getRemainingColumns()
	{
		return (byte) (7 - columnIndex);
	}

}
